﻿using StackExchange.Redis;
using System.Text.Json;

namespace WebSocketApi.CacheManager;
public class RedisCacheService : ICacheContext
{
    private static ConnectionMultiplexer Conn { get; set; }
    private static IDatabase RedisDb { get; set; }

    /// <summary>
    /// 初始化连接
    /// </summary>
    /// <param name="conn"></param>
    /// <param name="db">默认DB</param>
    public static void Init(string conn, int db = 0)
    {
        Conn = ConnectionMultiplexer.Connect(conn);
        RedisDb = Conn.GetDatabase(db);
    }

    /// <summary>
    /// RedisCacheContext
    /// </summary>
    public RedisCacheService()
    {
    }

    /// <summary>
    /// 是否存在此缓存
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public bool Exists(string key)
    {
        return RedisDb.KeyExists(key);
    }

    /// <summary>
    /// 获取缓存对象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key"></param>
    /// <returns></returns>
    public T GetCache<T>(string key)
    {
        RedisValue value = RedisDb.StringGet(key);
        if (!value.HasValue)
            return default;

        if (typeof(T) == typeof(string))
        {
            return (T)Convert.ChangeType(value, typeof(T));
        }
        else
        {
            return JsonSerializer.Deserialize<T>(value);
        }
    }

    /// <summary>
    /// 设置缓存
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    public bool SetCache<T>(string key, T value)
    {
        if (typeof(T) == typeof(string))
        {
            return RedisDb.StringSet(key, value?.ToString());
        }
        else
        {
            return RedisDb.StringSet(key, JsonSerializer.Serialize(value));
        }
    }

    /// <summary>
    /// 设置缓存
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    /// <param name="expire"></param>
    public bool SetCache<T>(string key, T value, DateTime expire)
    {
        if (typeof(T) == typeof(string))
        {
            return RedisDb.StringSet(key, value?.ToString(), expire - DateTime.Now);
        }
        else
        {
            return RedisDb.StringSet(key, JsonSerializer.Serialize(value), expire - DateTime.Now);
        }
    }

    /// <summary>
    /// 删除缓存
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public bool Remove(string key)
    {
        return RedisDb.KeyDelete(key);
    }

    /// <summary>
    /// 重命名Key
    /// </summary>
    /// <param name="key"></param>
    /// <param name="newKey"></param>
    /// <returns></returns>
    public bool RenameKey(string key, string newKey)
    {
        return RedisDb.KeyRename(key, newKey);
    }

}
